#include "gfx.h"

Uint32 getPixel32( SDL_Surface *surface, int x, int y )
{
    //Convert the pixels to 32 bit
    Uint32 *pixels = (Uint32 *)surface->pixels;

    //Get the requested pixel
    return pixels[(y*surface->w)+x];
}

void setPixel32(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    //Convert the pixels to 32 bit
    Uint32 *pixels = (Uint32 *)surface->pixels;

    //Set the pixel
    pixels[(y*surface->w )+x]=pixel;
}

SDL_Surface* gfx_loadImage(const char* filename)
{
	// Copy filename
	char filenameCopy[MAX_PATH];
	sprintf(filenameCopy, filename);

    // Temporary storage for the image that's loaded
    SDL_Surface* loadedImage=NULL;

    // The optimized image that will be used
    SDL_Surface* optimizedImage=NULL;

    // Load the image
    loadedImage = IMG_Load(filenameCopy);

	// If nothing went wrong in loading the image
    if(loadedImage!=NULL)
    {
        // Create an optimized image
        optimizedImage=SDL_DisplayFormatAlpha(loadedImage);

        // Free the old image
        SDL_FreeSurface(loadedImage);
    }

	// Return the optimized image
    return optimizedImage;
}

void gfx_applySurface(u32 x, u32 y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip)
{
    // Make a temporary rectangle to hold the offsets
    SDL_Rect offset;

    //Give the offsets to the rectangle
    offset.x=x;
    offset.y=y;

    // Blit the surface
    SDL_BlitSurface(source, clip, destination, &offset);
}

void gfx_resizeSurface(SDL_Surface* surface, u16 newWidth, u16 newHeight)
{
	// Create new surface
	SDL_Surface* newSurface=NULL;
	newSurface=SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,newWidth,newHeight,32,0,0,0,0);

	// Transfer pixel data between surfaces
	SDL_Rect clip;
	clip.w=1;
	clip.h=1;
	u16 newX=0;
	u16 newY=0;
	while (true)
	{
		clip.y=newY*((float) surface->h/(float) newHeight);
		while (true)
		{
			clip.x=newX*((float) surface->w/(float) newWidth);
			gfx_applySurface(newX,newY, surface, newSurface, &clip);
			newX++;
			if (newX>newWidth)
			{
				newX=0;
				break;
			}
		}
		newY++;
		if (newY>newHeight)
		{
			break;
		}
	}

	// Free old surface
	SDL_FreeSurface(surface);

	// Redirect pointer
	*surface= *newSurface;
}

SDL_Surface* gfx_createColorTransformedSurface(SDL_Surface* source, u32* transformArray, u16 iterations)
{
	// Make a copy of source surface
	SDL_Surface* returnSurface=NULL;
	returnSurface=source;
	returnSurface->refcount++;

	// Iterate as many times as specified
	for (u16 i=0; i<iterations; i++)
	{
		// Initiate pixels
		u32 pixelFrom=transformArray[i*2];
		u32 pixelTo=transformArray[i*2+1];

		// Loop through surface
		for (u16 j=0; j<source->w; j++)
		{
			for (u16 k=0; k<source->h; k++)
			{
				// Get pixel at current position
				u32 pixelCurrent=getPixel32(returnSurface,j,k);

				// If piexels match
				if (pixelCurrent==pixelFrom)
				{
					// Transform the pixel
					setPixel32(returnSurface, j, k, pixelTo);
				}
			}
		}
	}
	return returnSurface;
}
